home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 223 / emacssrc / term.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-17  |  21.6 KB  |  1,100 lines

  1. /*
  2.  * file termio.c:
  3.  *
  4.  * The functions in this file
  5.  * negotiate with the operating system
  6.  * for characters, and write characters in
  7.  * a barely buffered fashion on the display.
  8.  * All operating systems.
  9.  * dal: added highlight and normal text attribute
  10.  * functions, but ansi and termcap need to have
  11.  * the hooks filled in.
  12.  */
  13. #include    <stdio.h>
  14. #include    "ed.h"
  15.  
  16. #if    AtST
  17. /* overlay "me2"    dal: can't do this in Alcyon C */
  18.  
  19. /*
  20.  * dal: These functions switch the mouse in and out of cursor streaming mode
  21.  */
  22. mouse_live()
  23.     {
  24.     Ikbdws(4, m_init);
  25.     }
  26.  
  27. mouse_dead()
  28.     {
  29.     Ikbdws(2, "\007\001\010");
  30.     }
  31.  
  32. /*
  33.  * dal: These functions adjust to motion sensitivity of the mouse 
  34.  */
  35. dxmouse(f, n)
  36.     int f, n;
  37.     {
  38.     if (f && (n > 0) && (n < 256)) 
  39.         {
  40.         mcur_dx = ((char) n);
  41.         Ikbdws(2, m_move);
  42.         mlwrite("Horizontal mouse motion scale set to %d.", n);
  43.         return(TRUE);
  44.         }
  45.     return(FALSE);
  46.     }
  47.  
  48. dymouse(f, n)
  49.     int f, n;
  50.     {
  51.     if (f && (n > 0) && (n < 256)) 
  52.         {
  53.         mcur_dy = ((char) n);
  54.         Ikbdws(2, m_move);
  55.         mlwrite("Vertical mouse motion scale set to %d.", n);
  56.         return(TRUE);
  57.         }
  58.     return(FALSE);
  59.     }
  60. #endif    /* AtST */
  61.  
  62. #if    VMS
  63. #include    <stsdef.h>
  64. #include    <ssdef.h>
  65. #include    <descrip.h>
  66. #include    <iodef.h>
  67. #include    <ttdef.h>
  68.  
  69. #define    NIBUF    128            /* Input  buffer size        */
  70. #define    NOBUF    1024            /* MM says bug buffers win!    */
  71. #define    EFN    0            /* Event flag            */
  72.  
  73. char    obuf[NOBUF];            /* Output buffer        */
  74. nt    nobuf;                /* # of bytes in above        */
  75. char    ibuf[NIBUF];            /* Input buffer            */
  76. nt    nibuf;                /* # of bytes in above        */
  77. int    ibufi;                /* Read index            */
  78. int    oldmode[2];            /* Old TTY mode bits        */
  79. int    newmode[2];            /* New TTY mode bits        */
  80. short    iochan;                /* TTY I/O channel        */
  81. #endif    /* VMS */
  82.  
  83. #if    CPM
  84. #include    <bdos.h>
  85. #endif    /* CPM */
  86.  
  87. #if    MSDOS            /* dal: Microsoft C v4.0 */
  88. #include      <conio.h>
  89. #include      <dos.h>
  90. #if    TTFUNC
  91. #define    SCRCHRS    1920        /* # of character on the screen */
  92. int    *scrptr;        /* screen base address */
  93. int    abscup = 0;        /* absolute cursor position */
  94. int    curattr = 0x0700;    /* current output attributes */
  95. #endif    /* TTFUNC */
  96. #endif    /* MSDOS */
  97.  
  98. #if    V7
  99. #include    <sgtty.h>        /* for stty/gtty functions */
  100. struct  sgttyb  ostate;            /* saved tty state */
  101. struct    sgttyb    nstate;            /* values for editor mode */
  102. #endif    /* V7 */
  103.  
  104. /*
  105.  * This function is called once
  106.  * to set up the terminal device streams.
  107.  * On VMS, it translates SYS$INPUT until it
  108.  * finds the terminal, then assigns a channel to it
  109.  * and sets it raw. On CPM it is a no-op.
  110.  * dal: added functions to determine screen size
  111.  *      at run time.
  112.  */
  113. ttopen()
  114.     {
  115. #if    VMS
  116.     struct    dsc$descriptor    idsc;
  117.     struct    dsc$descriptor    odsc;
  118.     char    oname[40];
  119.     int    iosb[2];
  120.     int    status;
  121.  
  122.     odsc.dsc$a_pointer = "SYS$INPUT";
  123.     odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  124.     odsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  125.     odsc.dsc$b_class   = DSC$K_CLASS_S;
  126.     idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  127.     idsc.dsc$b_class   = DSC$K_CLASS_S;
  128.     do 
  129.         {
  130.         idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  131.         idsc.dsc$w_length  = odsc.dsc$w_length;
  132.         odsc.dsc$a_pointer = &oname[0];
  133.         odsc.dsc$w_length  = sizeof(oname);
  134.         status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  135.         if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  136.             exit(status);
  137.         if (oname[0] == 0x1B) 
  138.             {
  139.             odsc.dsc$a_pointer += 4;
  140.             odsc.dsc$w_length  -= 4;
  141.             }
  142.         }
  143.         while (status == SS$_NORMAL);
  144.     status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  145.     if (status != SS$_NORMAL)
  146.         exit(status);
  147.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  148.               oldmode, sizeof(oldmode), 0, 0, 0, 0);
  149.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  150.         exit(status);
  151.     newmode[0] = oldmode[0];
  152.     newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
  153.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  154.               newmode, sizeof(newmode), 0, 0, 0, 0);
  155.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  156.         exit(status);
  157. #endif
  158. #if    CPM
  159. #endif
  160. #if    MSDOS
  161.     union REGS rg;
  162.     int mode;
  163.  
  164.     /* set cursor size */
  165.     rg.h.ah = 1;
  166.     rg.h.ch = 0;
  167.     rg.h.cl = 12;
  168.     int86( 16, &rg, &rg );
  169. #if    TTFUNC
  170.     /* get cursor location */
  171.     rg.h.ah = 3;
  172.     rg.h.bh = 0;
  173.     int86( 16, &rg, &rg );
  174.     abscup = rg.h.dh * 80;        /* row */
  175.     abscup += rg.h.dl;        /* col */
  176.     curattr = 0x0700;        /* normal character attributes */
  177.     rg.h.ah = 15;
  178.     int86( 16, &rg, &rg );        /* get current display mode */
  179.     mode = rg.h.al;
  180.     scrptr = ((int *) ((mode == 7) ? 0xB0000000L : 0xB8000000L));
  181. #endif    /* TTFUNC */
  182. #endif    /* MSDOS */
  183. #if    AtST
  184.     register long *a;
  185.     register int n;
  186.  
  187.     a = Physbase();                /* dal: clean up what GEM */
  188.     a += 7680;                /* leaves at end of screen */
  189.     for( n=320; n--; *a++ = 0L )        /* (zero last 16 scanlines) */
  190.         ;
  191.     term.t_nrow = get_nrow() - 1;        /* dal: get screen size */
  192.     term.t_ncol = get_ncol();        /* from A-line variables */
  193.     Cursconf(2,0);                /* dal: blinking cursor    */
  194.     mouse_live();                /* dal: cursor stream mode */
  195. #endif
  196. #if    V7
  197.     gtty(1, &ostate);            /* save old state */
  198.     gtty(1, &nstate);            /* get base of new state */
  199.     nstate.sg_flags |= RAW;
  200.     nstate.sg_flags &= ~(ECHO|CRMOD);    /* no echo for now... */
  201.     stty(1, &nstate);            /* set mode */
  202. #endif
  203.     }
  204.  
  205. /*
  206.  * This function gets called just
  207.  * before we go back home to the command interpreter.
  208.  * On VMS it puts the terminal back in a reasonable state.
  209.  * Another no-operation on CPM.
  210.  */
  211. ttclose()
  212.     {
  213. #if    VMS
  214.     int    status;
  215.     int    iosb[1];
  216.  
  217.     ttflush();
  218.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  219.          oldmode, sizeof(oldmode), 0, 0, 0, 0);
  220.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  221.         exit(status);
  222.     status = SYS$DASSGN(iochan);
  223.     if (status != SS$_NORMAL)
  224.         exit(status);
  225. #endif
  226. #if    CPM
  227. #endif
  228. #if    AtST
  229.     Cursconf(2,0);                /* dal: blinking cursor    */
  230.     mouse_dead();                /* dal: reset mouse mode */
  231. #endif
  232. #if    MSDOS
  233.     union REGS rg;
  234.  
  235.     /* reset cursor size */
  236.     rg.h.ah = 1;
  237.     rg.h.ch = 6;
  238.     rg.h.cl = 7;
  239.     int86(16, &rg, &rg);
  240. #endif
  241. #if    V7
  242.     stty(1, &ostate);
  243. #endif
  244.     }
  245.  
  246. /*
  247.  * Write a character to the display.
  248.  * On VMS, terminal output is buffered, and
  249.  * we just put the characters in the big array,
  250.  * after cheching for overflow. On CPM terminal I/O
  251.  * unbuffered, so we just write the byte out.
  252.  * Ditto on MS-DOS (use the very very raw console
  253.  * output routine).
  254.  */
  255. ttputc(c)
  256.     {
  257. #if    VMS
  258.     if (nobuf >= NOBUF)
  259.         ttflush();
  260.     obuf[nobuf++] = c;
  261. #endif
  262. #if    CPM
  263.     bios(BCONOUT, c, 0);
  264. #endif
  265. #if    AtST
  266.     Bconout(2, c);
  267. #endif
  268. #if    MSDOS
  269.     c &= 0xFF;
  270.     bdos(2, c, 0);                /* conout() */
  271. #endif
  272. #if    V7
  273.     fputc(c, stdout);
  274. #endif
  275.     }
  276.  
  277. /*
  278.  * Write a character to the display without VT52
  279.  * emulation (if possible). On some systems, this
  280.  * provides a faster output if VT52 functionality
  281.  * is not needed. On VMS, terminal output is
  282.  * buffered, and we just put the characters in
  283.  * the big array, after cheching for overflow.
  284.  * On CPM terminal I/O unbuffered, so we just
  285.  * write the byte out.  Ditto on MS-DOS (use the
  286.  * very very raw console output routine).
  287.  */
  288. ttqputc(c)            /* dal: added */
  289. #if AtST
  290. register int c;
  291. #endif
  292.     {
  293. #if    VMS
  294.     if (nobuf >= NOBUF)
  295.         ttflush();
  296.     obuf[nobuf++] = c;
  297. #endif
  298. #if    CPM
  299.     bios(BCONOUT, c, 0);
  300. #endif
  301. #if    AtST
  302.     /* dal: EXTERMEMLY non-portable, but FAST! c==r7 in Alcyon v4.14 */
  303.     if(c < ' ') 
  304.         {
  305.         asm("    move.w    r7,-(sp)    ");
  306.         asm("    move.w    #2,-(sp)    ");    /* Bconout(2, c); */
  307.         }
  308.     else 
  309.         {
  310.         asm("    move.w    r7,-(sp)    ");    /* Bconout(5, c); */
  311.         asm("    move.w    #5,-(sp)    ");
  312.         }
  313.     asm("    move.w    #3,-(sp)    ");
  314.     asm("    trap    #13        ");
  315.     asm("    addq.l    #6,sp        ");
  316. #endif
  317. #if    MSDOS
  318. #if    TTFUNC            /* dal: this SHOULD be faster */
  319.     c &= 0xFF;                /* mask character */
  320.     if (c < ' ')                 /* control character */
  321.         {
  322.         if (c == '\b')
  323.             --abscup;
  324.         else if (c == '\r')
  325.             abscup -= (abscup % 80);
  326.         return;
  327.         }
  328.     *(scrptr + abscup) = (curattr | c);    /* put character w/ attr. */
  329.     ++abscup;                /* increment cursor position */
  330. #else
  331.     union REGS rg;
  332.  
  333.     c &= 0xFF;
  334.     rg.h.ah = 0x0E;                /* write char as TTY */
  335.     rg.h.al = c;
  336.     int86(0x10, &rg, &rg);            /* bios video service */
  337.     /* ...and if all else fails...    bdos(2, c, 0); */
  338. #endif
  339. #endif    /* MSDOS */
  340. #if    V7
  341.     fputc(c, stdout);
  342. #endif
  343.     }
  344.  
  345. /*
  346.  * Flush terminal buffer. Does real work
  347.  * where the terminal output is buffered up. A
  348.  * no-operation on systems where byte at a time
  349.  * terminal I/O is done.
  350.  */
  351. ttflush()
  352.     {
  353. #if    VMS
  354.     int    status;
  355.     int    iosb[2];
  356.  
  357.     status = SS$_NORMAL;
  358.     if (nobuf != 0) 
  359.         {
  360.         status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  361.              iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  362.         if (status == SS$_NORMAL)
  363.             status = iosb[0] & 0xFFFF;
  364.         nobuf = 0;
  365.         }
  366.     return (status);
  367. #endif
  368. #if    CPM
  369. #endif
  370. #if    MSDOS
  371. #if    TTFUNC
  372.     cursync();        /* move DOS cursor to internal cursor pos. */
  373. #endif
  374. #endif
  375. #if    AtST
  376. #endif
  377. #if    V7
  378.     fflush(stdout);
  379. #endif
  380.     }
  381.  
  382. #if    AtST
  383. #define    LMOUSE    (FUNC|ALT|0x74)
  384. #define    RMOUSE    (FUNC|ALT|0x75)
  385. /*
  386.  * dal: Special subordinate input function to ease mouse button aliasing
  387.  */
  388. _ttgetc()
  389.     {
  390.     register long key;
  391.     register int  kbs;
  392.     register int  c;
  393.     register int  k;
  394.  
  395.     key = Bconin(2);    /* key code in upper word */
  396.     kbs = Kbshift(-1);    /* read shift and alt keys */
  397.     c = (int)(key & 0xFF);
  398.     k = (int)((key >> 16) & 0xFF);
  399.     if (c==0 && k==0x03)
  400.         return( CTLX|' ' );
  401.     if ( c==0
  402.       || k==0x0E || k==0x53        /* bs & del    */
  403.       || k==0x4B || k==0x4D        /* arrow keys    */
  404.       || k==0x48 || k==0x50
  405.       || k==0x52 || k==0x47    )     /* ins & clr    */
  406.         {
  407.         if (k>=0x54 && k<=0x5D)    /* shifted F1..f10 ->    */
  408.             k -= 0x19;    /*    unshifted codes    */
  409.         else if (k==0x48 || k==0x50)     /* dal: kludge up/dn arrows */
  410.             {
  411.             if (kbs & 0x0C)        /* dal: for ctrl & alt */
  412.                 k |= ALT;
  413.             }
  414.                else if ((k==0x74 || k==0x75) && !(kbs&0x04))    /* mouse? */
  415.             k |= ALT;
  416.         c = FUNC | k;
  417.         if (kbs & 0x0F)        /* Ctrl, Shift or Alt?    */
  418.             c |= SHFT;
  419.         }
  420.     return (c);
  421.     }
  422. #endif
  423.  
  424. /*
  425.  * Read a character from the terminal,
  426.  * performing no editing and doing no echo at all.
  427.  * More complex in VMS than almost anyplace else, which
  428.  * figures. Very simple on CPM, because the system can
  429.  * do exactly what you want.
  430.  */
  431. ttgetc()
  432.     {
  433. #if    VMS
  434.     int    status;
  435.     int    iosb[2];
  436.     int    term[2];
  437.  
  438.     while (ibufi >= nibuf) 
  439.         {
  440.         ibufi = 0;
  441.         term[0] = 0;
  442.         term[1] = 0;
  443.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  444.              iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  445.         if (status != SS$_NORMAL)
  446.             exit(status);
  447.         status = iosb[0] & 0xFFFF;
  448.         if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  449.             exit(status);
  450.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  451.         if (nibuf == 0) 
  452.             {
  453.             status = sys$qiow(EFN, iochan, IO$_READLBLK,
  454.                  iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  455.             if (status != SS$_NORMAL
  456.             || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  457.                 exit(status);
  458.             nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  459.             }
  460.         }
  461.     return (ibuf[ibufi++] & 0xFF);        /* Allow multinational    */
  462. #endif
  463. #if    CPM
  464.     return (biosb(BCONIN, 0, 0));
  465. #endif
  466. #if    AtST
  467.     register int c;
  468.  
  469.     c = _ttgetc();
  470.     if(mousef) 
  471.         {
  472.         if(c == LMOUSE)         /* execute left alias */
  473.             {
  474.             if (!mb_left)
  475.                 mlpending("Left mouse button not bound");
  476.             return(mb_left);
  477.             }
  478.         if(c == RMOUSE)         /* execute right alias */
  479.             {
  480.             if (!mb_right)
  481.                 mlpending("Right mouse button not bound");
  482.             return(mb_right);
  483.             }
  484.         if(c == (SHFT|LMOUSE))     /* define left alias */
  485.             {
  486.             mlwrite("Bind what key to left mouse button?");
  487.             Ikbdws(0, "\010");        /* no mouse motion */
  488.             c = _ttgetc();
  489.             if (c==0x07 || c==(FUNC|0x61)) 
  490.                 {
  491.                 mlpending("[aborted]");
  492.                 }
  493.             else if (c==LMOUSE || c==(SHFT|LMOUSE)) 
  494.                 {
  495.                 mb_left = 0;
  496.                 mlpending("Left mouse button undefined.");
  497.                 }
  498.             else
  499.                 mb_left = c;
  500.             Ikbdws(2, m_move);        /* mouse motion */
  501.             return(0);
  502.             }
  503.         if (c == (SHFT|RMOUSE))     /* define left alias */
  504.             {
  505.             mlwrite("Bind what key to right mouse button?");
  506.             Ikbdws(0, "\010");        /* no mouse motion */
  507.             c = _ttgetc();
  508.             if(c==0x07 || c==(FUNC|0x61)) 
  509.                 {
  510.                 mlpending("[aborted]");
  511.                 }
  512.             else if(c==RMOUSE || c==(SHFT|RMOUSE)) 
  513.                 {
  514.                 mb_right = 0;
  515.                 mlpending("Right mouse button undefined.");
  516.                 }
  517.             else
  518.                 mb_right = c;
  519.             Ikbdws(2, m_move);        /* mouse motion */
  520.             return(0);
  521.             }
  522.         }
  523.     return(c);
  524. #endif
  525. #if    MSDOS
  526.     register int c, k, m, kbs;
  527.     union REGS rg;
  528.  
  529.     m = 0;
  530.  
  531.     rg.h.ah = 0x00;            /* read kbd char and scan-code */
  532.     int86( 0x16, &rg, &rg );    /* bios keyboard service */
  533.     c = rg.h.al;        /* ascii char */
  534.     k = rg.h.ah;        /* scancode */
  535.  
  536.     rg.h.ah = 0x02;            /* read kbd shift status */
  537.     int86( 0x16, &rg, &rg );    /* bios keyboard service */
  538.     kbs = rg.h.al;        /* kbd status */
  539.  
  540.     if ( k==0x0E || k==0x53        /* bs & del    */
  541.       || k==0x4B || k==0x4D        /* arrow keys    */
  542.       || k==0x48 || k==0x50
  543.       || k==0x52 || k==0x47        /* ins & clr    */
  544.       || (c==0 && k!=0x03) )     /* other function keys or
  545.         {
  546.                        Alt-, but leave ^@    */
  547.         if (k>=0x54 && k<=0x5D)    /* shifted F1..f10 ->    */
  548.             k -= 0x19;    /*    unshifted codes    */
  549.  
  550.         if (k==0x48 || k==0x50)        /* dal: kludge up/dn arrows */
  551.             if (kbs & 0x0C)        /* dal: for ctrl & alt */
  552.                 k |= ALT;
  553.  
  554.         c = FUNC | k;
  555.         if (kbs & 0x0F)        /* Ctrl, Shift or Alt?    */
  556.             c |= SHFT;
  557.         }
  558.     return (c);
  559. #endif
  560. #if    V7
  561.     return(fgetc(stdin));
  562. #endif
  563.     }
  564.  
  565.  
  566. /*
  567.  * file vt52.c:
  568.  *
  569.  * The routines in this file
  570.  * provide support for VT52 style terminals
  571.  * over a serial line. The serial I/O services are
  572.  * provided by routines in "termio.c". It compiles
  573.  * into nothing if not a VT52 style device. The
  574.  * bell on the VT52 is terrible, so the "beep"
  575.  * routine is conditionalized on defining BEL.
  576.  */
  577.  
  578. #if    VT52
  579.  
  580. #if AtST
  581. get_nrow()        /* dal: added */
  582.     {
  583.     asm( "    dc.w    $a000        " );
  584.     asm( "    move.w    -$2a(a0),d0    " );
  585.     asm( "    addq.l    #1,d0        " );
  586.     }
  587.  
  588. get_ncol()        /* dal: added */
  589.     {
  590.     asm( "    dc.w    $a000        " );
  591.     asm( "    move.w    -$2c(a0),d0    " );
  592.     asm( "    addq.l    #1,d0        " );
  593.     }
  594.  
  595. #define    NROW    25
  596. #else
  597. #define    NROW    24            /* Screen size.            */
  598. #endif
  599. #define    NCOL    80            /* Edit if you want to.        */
  600.  
  601. #define    BIAS    0x20            /* Origin 0 coordinate bias.    */
  602. #define    ESC    0x1B            /* ESC character.        */
  603. #define BEL    0x07            /* ascii bell character        */
  604.  
  605. extern    int    ttopen();        /* Forward references.        */
  606. extern    int    ttgetc();
  607. extern    int    ttputc();
  608. extern    int    ttqputc();        /* dal: fast, non-VT52 output    */
  609. extern    int    ttflush();
  610. extern    int    ttclose();
  611. extern    int    vt52move();
  612. extern    int    vt52eel();
  613. extern    int    vt52eep();
  614. extern    int    vt52beep();
  615. extern    int    vt52open();
  616. extern    int    vt52hglt();
  617. extern    int    vt52nrml();
  618.  
  619. /*
  620.  * Dispatch table. All the
  621.  * hard fields just point into the
  622.  * terminal I/O code.
  623.  */
  624. TERM    term    = 
  625.     {
  626.     NROW-1,
  627.     NCOL,
  628.     vt52open,
  629.     ttclose,
  630.     ttgetc,
  631.     ttqputc,
  632.     ttflush,
  633.     vt52move,
  634.     vt52eel,
  635.     vt52eep,
  636.     vt52beep,
  637.     vt52hglt,        /* dal: added */
  638.     vt52nrml        /* dal: added */
  639.     };
  640.  
  641. vt52move(row, col)
  642.     {
  643.     ttputc(ESC);
  644.     ttputc('Y');
  645.     ttputc(row+BIAS);
  646.     ttputc(col+BIAS);
  647.     }
  648.  
  649. vt52eel()
  650.     {
  651.     ttputc(ESC);
  652.     ttputc('K');
  653.     }
  654.  
  655. vt52eep()
  656.     {
  657.     ttputc(ESC);
  658.     ttputc('J');
  659.     }
  660.  
  661. vt52beep()
  662.     {
  663. #ifdef    BEL
  664.     ttputc(BEL);
  665.     ttflush();
  666. #endif
  667.     }
  668.  
  669. vt52hglt()
  670.     {
  671.     ttputc(ESC);
  672.     ttputc('p');
  673.     }
  674.  
  675. vt52nrml()
  676.     {
  677.     ttputc(ESC);
  678.     ttputc('q');
  679.     }
  680.  
  681.  
  682. vt52open()
  683.     {
  684. #if    V7
  685.     register char *cp;
  686.     char *getenv();
  687.  
  688.     if ((cp = getenv("TERM")) == NULL) 
  689.         {
  690.         puts("Shell variable TERM not defined!");
  691.         exit(1);
  692.         }
  693.     if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) 
  694.         {
  695.         puts("Terminal type not 'vt52'or 'z19' !");
  696.         exit(1);
  697.         }
  698. #endif
  699.     ttopen();
  700.     }
  701.  
  702. #endif    VT52
  703.  
  704. /*
  705.  * file ansi.c:
  706.  *
  707.  * The routines in this file
  708.  * provide support for ANSI style terminals
  709.  * over a serial line. The serial I/O services are
  710.  * provided by routines in "termio.c". It compiles
  711.  * into nothing if not an ANSI device.
  712.  */
  713.  
  714. #if    ANSI
  715.  
  716. #define NROW    24            /* Screen size.            */
  717. #define NCOL    80            /* Edit if you want to.        */
  718. #define BEL    0x07            /* BEL character.        */
  719. define  ESC    0x1B            /* ESC character.        */
  720.  
  721. extern  int    ttopen();        /* Forward references.        */
  722. extern  int    ttgetc();
  723. extern  int    ttputc();
  724. extern  int    ttflush();
  725. extern  int    ttclose();
  726. extern  int    ansimove();
  727. extern  int    ansieeol();
  728. extern  int    ansieeop();
  729. extern  int    ansibeep();
  730. extern  int    ansiopen();
  731. extern    int    ansihglt();        /* dal: added */
  732. extern    int    ansinrml();        /* dal: added */
  733.  
  734. /*
  735.  * Standard terminal interface
  736.  * dispatch table. Most of the fields
  737.  * point into "termio" code.
  738.  */
  739. TERM    term    = 
  740.     {
  741.     NROW-1,
  742.     NCOL,
  743.     ansiopen,
  744.     ttclose,
  745.     ttgetc,
  746.     ttputc,
  747.     ttflush,
  748.     ansimove,
  749.     ansieeol,
  750.     ansieeop,
  751.     ansibeep,
  752.     ansihglt,        /* dal: added */
  753.     ansinrml        /* dal: added */
  754.     };
  755.  
  756. ansimove(row, col)
  757.     {
  758.     ttputc(ESC);
  759.     ttputc('[');
  760.     ansiparm(row+1);
  761.     ttputc(';');
  762.     ansiparm(col+1);
  763.     ttputc('H');
  764.     }
  765.  
  766. ansieeol()
  767.     {
  768.     ttputc(ESC);
  769.     ttputc('[');
  770.     ttputc('K');
  771.     }
  772.  
  773. ansieeop()
  774.     {
  775.     ttputc(ESC);
  776.     ttputc('[');
  777.     ttputc('J');
  778.     }
  779.  
  780. ansibeep()
  781.     {
  782.     ttputc(BEL);
  783.     ttflush();
  784.     }
  785.  
  786. ansihglt()        /* dal: added */
  787.     {
  788.     ttputc(ESC);
  789.     ttputc('[');
  790.     ttputc('1');
  791.     ttputc('m');
  792.     }
  793.  
  794. ansinrml()        /* dal: added */
  795.     {
  796.     ttputc(ESC);
  797.     ttputc('[');
  798.     ttputc('0');
  799.     ttputc('m');
  800.     }
  801.  
  802. ansiparm(n)
  803. register int    n;
  804.     {
  805.     register int    q;
  806.  
  807.     q = n/10;
  808.     if (q != 0)
  809.         ansiparm(q);
  810.     ttputc((n%10) + '0');
  811.     }
  812.  
  813. ansiopen()
  814.     {
  815. #if    V7
  816.     register char *cp;
  817.     char *getenv();
  818.  
  819.     if ((cp = getenv("TERM")) == NULL) 
  820.         {
  821.         puts("Shell variable TERM not defined!");
  822.         exit(1);
  823.         }
  824.     if (strcmp(cp, "vt100") != 0) 
  825.         {
  826.         puts("Terminal type not 'vt100'!");
  827.         exit(1);
  828.         }
  829. #endif
  830.     ttopen();
  831.     }
  832.  
  833. #endif    ANSI
  834.  
  835. /*
  836.  * file: tcap.c
  837.  *
  838.  * This file does the term stuff for systems
  839.  * that have 'termcap' flexibility.
  840.  */
  841.  
  842. #if TERMCAP
  843.  
  844. #define NROW    24
  845. #define NCOL    80
  846. #define BEL    0x07
  847. #define ESC    0x1B
  848.  
  849. extern int    ttopen();
  850. extern int    ttgetc();
  851. extern int    ttputc();
  852. extern int    ttflush();
  853. extern int     ttclose();
  854. extern int     tcapmove();
  855. extern int     tcapeeol();
  856. extern int    tcapeeop();
  857. extern int    tcapbeep();
  858. extern int    tcapopen();
  859. extern int    tcaphglt();        /* dal: added */
  860. extern int    tcapnrml();        /* dal: added */
  861. extern int    tput();
  862. extern char    *tgoto();
  863.  
  864. /* mb: following 3 entries added: */
  865.  
  866. extern int    tgetent();
  867. extern char    *tgetstr();
  868. extern int    tputs();
  869.  
  870. #define TCAPSLEN 315
  871.  
  872. char tcapbuf[TCAPSLEN];
  873. char    PC,
  874.     *CM,
  875.     *CL,
  876.     *CE,
  877.     *UP,
  878.     *CD;
  879.  
  880.  
  881. TERM term = 
  882.     {
  883.     NROW-1,
  884.     NCOL,
  885.     tcapopen,
  886.     ttclose,
  887.     ttgetc,
  888.     ttputc,
  889.     ttflush,
  890.     tcapmove,
  891.     tcapeeol,
  892.     tcapeeop,
  893.     tcapbeep,
  894.     tcaphglt,        /* dal: added */
  895.     tcapnrml        /* dal: added */
  896.     };
  897.  
  898. tcapopen()
  899.     {
  900.     char *getenv();
  901.     char *t, *p, *tgetstr();
  902.     char tcbuf[1024];
  903.     char *tv_stype;
  904.     char err_str[72];
  905.  
  906.     if ((tv_stype = getenv("TERM")) == NULL)
  907.         {
  908.         puts("Environment variable TERM not defined!");
  909.         exit(1);
  910.         }
  911.  
  912.     if((tgetent(tcbuf, tv_stype)) != 1)
  913.         {
  914.         sprintf(err_str, "Unknown terminal type %s!", tv_stype);
  915.         puts(err_str);
  916.         exit(1);
  917.         }
  918.  
  919.     p = tcapbuf;
  920.     t = tgetstr("pc", &p);
  921.     if(t)
  922.         PC = *t;
  923.  
  924.     CD = tgetstr("cd", &p);
  925.     CM = tgetstr("cm", &p);
  926.     CE = tgetstr("ce", &p);
  927.     UP = tgetstr("up", &p);
  928.  
  929.     if(CD == NULL || CM == NULL || CE == NULL || UP == NULL)
  930.         {
  931.         puts("Incomplete termcap entry\n");
  932.         exit(1);
  933.         }
  934.  
  935.     if (p >= &tcapbuf[TCAPSLEN])
  936.         {
  937.         puts("Terminal description too big!\n");
  938.         exit(1);
  939.         }
  940.     ttopen();
  941.     }
  942.  
  943. tcapmove(row, col)
  944.     register int row, col;
  945.     {
  946.     putpad(tgoto(CM, col, row));
  947.     }
  948.  
  949. tcapeeol()
  950.     {
  951.     putpad(CE);
  952.     }
  953.  
  954. tcapeeop()
  955.     {
  956.     putpad(CD);
  957.     }
  958.  
  959. tcapbeep()
  960.     {
  961.     ttputc(BEL);
  962.     }
  963.  
  964. tcaphglt()        /* dal: added */
  965.     {
  966.     }
  967.  
  968. tcapnrml()        /* dal: added */
  969.     {
  970.     }
  971.  
  972. putpad(str)
  973. char    *str;
  974.     {
  975.     tputs(str, 1, ttputc);
  976.     }
  977.  
  978. putnpad(str, n)
  979. char    *str;
  980.     {
  981.     tputs(str, n, ttputc);
  982.     }
  983. #endif TERMCAP
  984.  
  985. /*
  986.  * file ttfunc.c:
  987.  *
  988.  * dal: The routines in this file
  989.  * provide support implementation of terminal control
  990.  * through direct functions. The serial I/O services are
  991.  * provided by routines in "termio.c". It compiles
  992.  * into nothing if not an TTFUNC device.
  993.  */
  994.  
  995. #if    TTFUNC
  996.  
  997. #define NROW    25            /* Screen size.            */
  998. #define NCOL    80            /* Edit if you want to.        */
  999. #define BEL    0x07            /* BEL character.        */
  1000. #define ESC    0x1B            /* ESC character.        */
  1001.  
  1002. extern  int    ttopen();        /* Forward references.        */
  1003. extern  int    ttgetc();
  1004. extern  int    ttputc();
  1005. extern    int    ttqputc();
  1006. extern  int    ttflush();
  1007. extern  int    ttclose();
  1008. extern  int    funcmove();
  1009. extern  int    funceeol();
  1010. extern  int    funceeop();
  1011. extern  int    funcbeep();        /* needs processing of ^G by ttputc */
  1012. extern    int    funchglt();        /* dal: added */
  1013. extern    int    funcnrml();        /* dal: added */
  1014.  
  1015. /*
  1016.  * Standard terminal interface
  1017.  * dispatch table. Most of the fields
  1018.  * point into "termio" code.
  1019.  */
  1020. TERM    term    = 
  1021.     {
  1022.     NROW-1,
  1023.     NCOL,
  1024.     ttopen,
  1025.     ttclose,
  1026.     ttgetc,
  1027.     ttqputc,
  1028.     ttflush,
  1029.     funcmove,
  1030.     funceeol,
  1031.     funceeop,
  1032.     funcbeep,
  1033.     funchglt,        /* dal: added */
  1034.     funcnrml        /* dal: added */
  1035.     };
  1036.  
  1037. funcmove(row, col)
  1038.     {
  1039.     union REGS rg;
  1040.  
  1041.     /* set cursor location */
  1042.     rg.h.ah = 2;
  1043.     rg.h.bh = 0;
  1044.     rg.h.dh = row;
  1045.     rg.h.dl = col;
  1046.     int86(16, &rg, &rg);        /* set DOS physical cursor */
  1047.     abscup = (80 * row) + col;    /* calculate internal cursor */
  1048.     }
  1049.  
  1050. funceeol()
  1051.     {
  1052.     register int i, *ip;
  1053.  
  1054.     ip = scrptr + abscup;
  1055.     i = (abscup % 80);
  1056.     while(i++ < 80)
  1057.         *ip++ = 0x0700;
  1058.     }
  1059.  
  1060. funceeop()
  1061.     {
  1062.     register int i, *ip;
  1063.  
  1064.     ip = scrptr + abscup;
  1065.     for(i=abscup; i<SCRCHRS; ++i)
  1066.         *ip++ = 0x0700;
  1067.     }
  1068.  
  1069. funcbeep()
  1070.     {
  1071.     ttputc(BEL);
  1072.     ttflush();
  1073.     }
  1074.  
  1075. funchglt()        /* dal: added */
  1076.     {
  1077.     curattr = 0x0F00;        /* highlight character attributes */
  1078.     }
  1079.  
  1080. funcnrml()        /* dal: added */
  1081.     {
  1082.     curattr = 0x0700;        /* normal character attributes */
  1083.     }
  1084.  
  1085. cursync()        /* dal: make DOS cursor match internal position */
  1086.     {
  1087.     union REGS rg;
  1088.     int row, col;
  1089.  
  1090.     row = abscup / 80;
  1091.     col = abscup % 80;
  1092.     /* set cursor location */
  1093.     rg.h.ah = 2;
  1094.     rg.h.bh = 0;
  1095.     rg.h.dh = row;
  1096.     rg.h.dl = col;
  1097.     int86(16, &rg, &rg);        /* set DOS physical cursor */
  1098.     }
  1099. #endif
  1100.